﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint.WebPartPages;
using System.Web.UI;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using System.Xml;

using System.Xml.XPath;
using System.IO;
using System.Xml.Xsl;
using System.Web;
using System.ComponentModel;
using VPLink2013.Framework;
using System.Data.SqlClient;
using System.Data;
using Microsoft.SharePoint.Utilities;

namespace VPLink2013.Webparts
{
    [ToolboxData("<{0}:AnnounceViewWebPart runat=server></{0}:AnnounceViewWebPart>"),
    XmlRoot(Namespace = "VPLink2013.Webparts")]
    public class AnnonceViewWebPart : ListViewWebPart
    {
        private readonly int _listTemplate = 104;
        public override int ListTemplate
        {
            get { return _listTemplate; }
        }

        protected SPListItemCollection CurrentUserListItems
        {
            get
            {
                try
                {
                    if (_currentUserListItems == null)
                    {
                        //// publishing mode (get items from root site)
                        //if (ListID != null && ListID != Guid.Empty)
                        //{
                        //    SPList news = SPContext.Current.Web.Lists[ListID];
                        //    _currentUserListItems = news.Items;
                        //}
                        if (_webID != null && _webID != Guid.Empty)
                        {
                            if (_listID != null && _listID != Guid.Empty)
                            {
                                using (SPWeb web = SPContext.Current.Site.OpenWeb(_webID))
                                {
                                    SPList news = web.Lists[_listID];
                                    _currentUserListItems = news.Items;
                                }
                            }
                        }
                        else
                        {
                            if (_listID != null && _listID != Guid.Empty)
                            {
                                SPList news = SPContext.Current.Web.Lists[_listID];
                                _currentUserListItems = news.Items;
                            }
                        }
                    }
                    return _currentUserListItems;
                }
                catch (Exception e)
                {
                    Log.Write(e.Message + "\r\n" + e.StackTrace, System.Diagnostics.EventLogEntryType.Error);
                }
                return null;
            }
        }

        override public ToolPart[] GetToolParts()
        {
            ToolPart[] toolParts = new ToolPart[2];
            toolParts[0] = new ListViewToolPart();
            toolParts[1] = new WebPartToolPart();
            return toolParts;
        }

        protected override void RenderWebPart(HtmlTextWriter output)
        {
            try
            {
                ContextTrace.AddTrace("Debut");

                if (CurrentUserListItems != null && CurrentUserListItems.Count > 0)
                {
                    string itemId = string.Empty;
                    if (Page.Request.QueryString["ItemID"] != null) itemId = Page.Request.QueryString["ItemID"];

                    XmlDocument xmlDoc = new XmlDocument();
                    string strXmlListItems = "<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882' xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882' xmlns:rs='urn:schemas-microsoft-com:rowset' xmlns:z='#RowsetSchema'><rs:data>";

                    SPQuery query = new SPQuery();
                    query.Query = "<Where><Eq><FieldRef Name=\"ID\" /><Value Type='Counter'>" + itemId + "</Value></Eq></Where><OrderBy><FieldRef Name='Created' Ascending=\"FALSE\"/></OrderBy>";
                    SPListItemCollection lic = CurrentUserListItems.List.GetItems(query);
                    SPListItem item = null;
                    if (lic.Count > 0)
                    {
                        item = lic[0];
                    }
                    else
                    {
                        item = CurrentUserListItems[0];
                    }
                    strXmlListItems += item.Xml;
                    string TitreArticle = item.Title;
                    ContextTrace.AddTrace("Lecture données XML");

                    strXmlListItems += "</rs:data></xml>";
                    xmlDoc.LoadXml(strXmlListItems);
                    ContextTrace.AddTrace("strXmlListItems : " + strXmlListItems);

                    XmlNode nodeEditFormURL = xmlDoc.CreateNode(XmlNodeType.Element, "EditFormURL", "");
                    if (CurrentUserListItems.List.DoesUserHavePermissions(SPBasePermissions.EditListItems))
                    {
                        nodeEditFormURL.InnerText = CurrentUserListItems.List.Forms[PAGETYPE.PAGE_EDITFORM].ServerRelativeUrl + string.Format("?Source={0}?ItemID={1}&ID={1}", Page.Request.Path, itemId);
                    }
                    xmlDoc.DocumentElement.AppendChild(nodeEditFormURL);


                    string strValue = null;
                    try
                    {
                        strValue = item["Images"].ToString();
                    }
                    catch (System.Exception) { }

                    if (strValue != null)
                    {
                        string[] astrLines = strValue.Split(new string[1] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                        foreach (string strLine in astrLines)
                        {
                            string[] astrValeurs = strLine.Split(new string[1] { "=" }, StringSplitOptions.RemoveEmptyEntries);
                            if (astrValeurs.Length == 2)
                            {
                                XmlNode nodeImageArticle = xmlDoc.CreateNode(XmlNodeType.Element, astrValeurs[0], "");
                                nodeImageArticle.InnerText = astrValeurs[1];
                                xmlDoc.DocumentElement.AppendChild(nodeImageArticle);
                            }
                        }
                    }

                    ProcessLike(xmlDoc, TitreArticle);

                    WriteTraceXml(xmlDoc, "webpartAnnonceView");

                    ContextTrace.AddTrace("Nom fichier XSL : webpartAnnonceView.xsl");

                    string _pathVP = @"TEMPLATE\LAYOUTS\VPLink2013\XSL\Annonce\webpartAnnonceView.xsl";
                    string strXsl = SPUtility.GetVersionedGenericSetupPath(_pathVP, 15);

                    //string strXslTransformResult = ListViewWebPart.SetXslTransformer(xslDoc, xmlDoc);
                    string strXslTransformResult = GetTransform(xmlDoc.OuterXml, strXsl);
                    ContextTrace.AddTrace("Transformation XSL");
                    strXslTransformResult = strXslTransformResult.Replace("<?xml version=\"1.0\" encoding=\"utf-16\"?>", "");
                    strXslTransformResult = this.Page.Server.HtmlDecode(strXslTransformResult);

                    //string strPath = @"C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS\VentePrivee\Trace\";
                    //System.IO.File.WriteAllText(strPath + "Test.htm", strXslTransformResult);
                    output.Write(strXslTransformResult);
                    ContextTrace.AddTrace("strXslTransformResult : " + strXslTransformResult);

                    ContextTrace.AddTrace("Fin");
                }
            }
            catch (Exception e)
            {
                output.Write(e.Message + "\r\n" + e.StackTrace);
                ContextTrace.AddTrace("Erreur : " + e.Message + " / " + e.StackTrace);
            }
            ContextTrace.Save("", "webpartAnnonceView");
        }


        protected string GetTransform(string strXml, string strXslPath)
        {
            if (!System.IO.File.Exists(strXslPath))
            {
                return "File not exists : " + strXslPath;
            }

            ContextTrace.AddTrace("Debut chargement XML");
            XmlTextReader xtr = new XmlTextReader(new StringReader(strXml));
            XPathDocument xpd = new XPathDocument(xtr);
            xtr.Close();
            XPathNavigator nav = xpd.CreateNavigator();
            ContextTrace.AddTrace("Fin chargement XML");

            StringWriter sw = new StringWriter();
            string Html = "";
            try
            {
                XsltArgumentList argsList = new XsltArgumentList();
                XSLUtilities obj = new XSLUtilities();
                argsList.AddExtensionObject("urn:Avanade", obj);
                //xslTemplate.Transform(xmlDoc, argsList, sw);


                XslCompiledTransform xslt = new XslCompiledTransform();
                ContextTrace.AddTrace("Debut chargement XSL : " + strXslPath);
                xslt.Load(strXslPath);
                ContextTrace.AddTrace("Fin chargement XSL, debut transformation");
                xslt.Transform(nav, argsList, sw);
                ContextTrace.AddTrace("Fin transformation XSL");
                Html = sw.ToString();
                ContextTrace.AddTrace("Fin HTML ToString");
            }
            catch (System.Xml.Xsl.XsltException exc)
            {
                ContextTrace.AddTrace("Erreur XSL : " + exc.Message + ".LineNumber:" + exc.LineNumber + ",LinePosition:" + exc.LinePosition);
            }
            catch (System.Exception exc2)
            {
                ContextTrace.AddTrace("Erreur XSL : " + exc2.Message);
            }
            return Html;
        }
        
        /// <summary>
        ///	Uses Request.Form or Request.QueryString
        /// </summary>
        private string ParamFrm(string Name)
        {
            HttpRequest Request = Context.Request;
            string strValue;
            if (Request.Form.Count == 0)
            {
                strValue = Request.QueryString[Name];
            }
            else
            {
                strValue = Request.Form[Name];
                if (strValue == null || strValue == "undefined")
                {
                    strValue = Request.QueryString[Name];
                }
            }
            if (strValue == null || strValue == "undefined")
            {
                strValue = "";
            }
            strValue = strValue.Trim();

            if (strValue != "")
            {
                ContextTrace.AddTrace("ParamFrm : " + Name + " = " + strValue);
            }
            return strValue;
        }

        public string FormatLogin(string login)
        {
            string strLogin = login;
            int iPos = strLogin.IndexOf(@"\");
            if (iPos > 0)
            {
                strLogin = strLogin.Substring(iPos + 1);
            }
            return strLogin;
        }

        protected string GetValueConfigurationVP(SPList lst, string key)
        {
            string strValeur = "";

            SPListItemCollection items = lst.Items;
            foreach (SPListItem item in items)
            {
                string strCle = VPLink2013SPHelper.GetValue(item, "Nom");
                ContextTrace.AddTrace("GetConfigurationVP.strCle : " + strCle);
                if (strCle == key)
                {
                    strValeur = VPLink2013SPHelper.GetValue(item, "Valeur");
                    ContextTrace.AddTrace("GetConfigurationVP.strValeur : " + strValeur);
                    break;
                }
            }
            return strValeur;
        }

        public void ProcessLike(XmlDocument xmlDoc, string TitreArticle)
        {
            ContextTrace.AddTrace("ProcessLike.SPContext.Current.Web.Url : " + SPContext.Current.Web.Url);
            if (SPContext.Current.Web.Url != "http://vplink")
            {
                return;
            }
            string _pathVP = @"TEMPLATE\LAYOUTS\VPLink2013";
            string pathVP = SPUtility.GetVersionedGenericSetupPath(_pathVP, 15);
            ConfigVPLink2013 conf = FileSerialization.CreateObjFromXML<ConfigVPLink2013>(string.Format(@"{0}\Config\ConfigVPLink2013.xml", pathVP));

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                ContextTrace.AddTrace("ProcessLike");

                SPWeb web = SPContext.Current.Web;

                string strList = "ConfigurationVP";
                ContextTrace.AddTrace("ProcessLike.strList.ConfigurationVP : " + strList);

                SPList lstConfig = web.Lists[strList];

                string ConfigLike = GetValueConfigurationVP(lstConfig, "Like");

                // Inactif
                // Article seul
                // Partout
                if (ConfigLike == "Inactif")
                {
                    ContextTrace.AddTrace("ProcessLike.RETURN : ConfigLike != Actif : " + ConfigLike);
                    return;
                }

                int nbLike = 0;
                string UsersLike = "";
                string DateLike = "";

                XmlNode nodeLike = xmlDoc.CreateNode(XmlNodeType.Element, "Like", "");
                nodeLike.InnerText = ConfigLike;
                xmlDoc.DocumentElement.AppendChild(nodeLike);
                ContextTrace.AddTrace(string.Format("Like : {0}", ConfigLike));

                string strIdAnnonce = ParamFrm("ItemID");
                if (string.IsNullOrEmpty(strIdAnnonce))
                {
                    ContextTrace.AddTrace("ProcessLike.RETURN : string.IsNullOrEmpty(strIdAnnonce)");
                    return;
                }

                string strSql = "SELECT NbLike, UsersLike, DateLike FROM LikeArticle WHERE IdArticle = " + strIdAnnonce;
                ContextTrace.AddTrace("strSql : " + strSql);

                SqlConnection conn = VPLink2013SqlHelper.GetConnection(conf.Connection.ConnectionString);
                SqlCommand command = VPLink2013SqlHelper.GetCommand(conn, strSql);

                if (conn.State == ConnectionState.Closed)
                {
                    ContextTrace.AddTrace("La connexion SQL est fermée");
                    ContextTrace.AddTrace("conn.ConnectionString : " + conn.ConnectionString);
                    return;
                }

                SqlDataReader Reader = command.ExecuteReader();
                if (Reader.Read())
                {
                    nbLike = VPLink2013SqlHelper.GetValueReaderInt(Reader, 0);
                    UsersLike = VPLink2013SqlHelper.GetValueReader(Reader, 1);
                    DateLike = VPLink2013SqlHelper.GetValueReader(Reader, 2);
                }
                VPLink2013SqlHelper.CloseReader(conn, Reader);

                bool UserCrtLike = false;

                ContextTrace.AddTrace("this.Context.User.Identity.Name : " + this.Context.User.Identity.Name);
                string strUserCrtLogin = FormatLogin(this.Context.User.Identity.Name);
                ContextTrace.AddTrace("strUserCrtLogin : " + strUserCrtLogin);

                string UsersLikeFormat = "," + UsersLike + ",";
                string UserLoginFormat = "," + strUserCrtLogin + ",";
                if (UsersLikeFormat.Contains(UserLoginFormat))
                {
                    UserCrtLike = true;
                }

                string strAction = ParamFrm("MyAction");
                if (strAction == "jaime")
                {
                    ContextTrace.AddTrace("Action jaime à traiter");

                    //if utilisateur crt n'a pas déjà "liké" => je fais ce traitement
                    if (!UserCrtLike)
                    {
                        if (nbLike == 0)
                        {
                            UsersLike = strUserCrtLogin;
                            DateLike = DateTime.Now.ToString("dd/MM/yyyy HH:mm");
                            strSql = "INSERT INTO LikeArticle (UrlSite, NomListe, IdArticle, TitreArticle, NbLike, UsersLike, DateLike) "
                                + " VALUES ('http://vplink', 'NewsVP', " + strIdAnnonce + ", '" + TitreArticle.Replace("'", "''") + "', 1, '" + UsersLike + "', '" + DateLike + "')";
                        }
                        else
                        {
                            nbLike += 1;
                            UsersLike += "," + strUserCrtLogin;
                            DateLike += "," + DateTime.Now.ToString("dd/MM/yyyy HH:mm");
                            strSql = "UPDATE LikeArticle SET NbLike = " + nbLike.ToString()
                                + ", UsersLike = '" + UsersLike + "'"
                                + ", DateLike = '" + DateLike + "'"
                                + " WHERE IdArticle = " + strIdAnnonce;
                        }

                        conn = VPLink2013SqlHelper.GetConnection(conf.Connection.ConnectionString);
                        command = VPLink2013SqlHelper.GetCommand(conn, strSql);
                        command.ExecuteNonQuery();
                        conn.Close();

                        XmlNode nodeLikeProcessed = xmlDoc.CreateNode(XmlNodeType.Element, "LikeProcessed", "");
                        nodeLikeProcessed.InnerText = "OK";
                        xmlDoc.DocumentElement.AppendChild(nodeLikeProcessed);
                        ContextTrace.AddTrace("LikeProcessed : OK");
                        UserCrtLike = true;
                    }
                }

                if (UserCrtLike)
                {
                    XmlNode nodeUserCrtLike = xmlDoc.CreateNode(XmlNodeType.Element, "UserCrtLike", "");
                    nodeUserCrtLike.InnerText = "OK";
                    xmlDoc.DocumentElement.AppendChild(nodeUserCrtLike);
                    ContextTrace.AddTrace("UserCrtLike : " + nodeUserCrtLike.InnerText);
                }

                XmlNode nodeNbLike = xmlDoc.CreateNode(XmlNodeType.Element, "NbLike", "");
                nodeNbLike.InnerText = nbLike.ToString();
                xmlDoc.DocumentElement.AppendChild(nodeNbLike);
                ContextTrace.AddTrace("NbLike : " + nodeNbLike.InnerText);
            });
        }
    }
}
